import MicrophoneIcon from '@/assets/microphone-icon.svg'
import { showMessage } from '@/components/antd-comp/message'
import { Textarea } from '@/components/bs-ui/input'
import axios from '@/controllers/request'
import { useBuriedEvent } from '@/util/buried'
import { generateUUIDv4 } from '@/util/utils'
import type { UploadProps } from 'antd'
import { Divider, Tooltip, Upload, message,Modal, Checkbox,Dropdown } from 'antd'
import JSON5 from 'json5'
import { uniqueId } from 'lodash'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { showWarning } from '../antd-comp/message/useNotification'
import SwitchComponent from '../antd-comp/switch'
import RecommendedCont from './RecommendedCont'
import { useChatStore } from './chatStore'
import { ASSISTANT_STATUS, AgentStatus, CITATION_TYPE, ROLE_EMPTY_ERROR } from './constants'
import './styles.less'
import { ChatMessageType, ChatResponseType } from './types'
import { getFileIconByFileName, getValidChatMsg } from './utils'
import { readFileLibDatabase } from '@/controllers/API'
import { BookOpen,Paperclip,ImageIcon } from 'lucide-react'
import { Spin } from 'antd';

const ACCEPT_FILES = [
  // 'png',
  // 'jpg',
  // 'jpeg',
  'pdf',
  'docx',
  'doc',
  'ppt',
  'pptx',
  'wav',
  'pcm',
  'ogg-opus',
  'speex',
  'silk',
  'mp3',
  'm4a',
  'aac',
  'amr'
]
export default function ChatInput({
  clear,
  form,
  questions,
  inputForm,
  chatUrl,
  assistantId,
  conversation,
  recommendedHid,
  regenerate,
  prompt = '',
  conversationId = '',
  disabled = false,
  tips = '',
  modelName = '',
  userName = '',
  // 会话中判断参数
  chattingFun,
  // 联网开关
  supportSearch = false,
  setUploading,
}) {
  const { t } = useTranslation()
  const [formShow, setFormShow] = useState(false)
  const [showWhenLocked, setShowWhenLocked] = useState(false) // 强制开启表单按钮，不限制于input锁定
  const [inputLock, setInputLock] = useState({ locked: false, reason: '' })
  // 会话暂停参数
  const isPaused = useRef(false)
  const controller = useRef(new AbortController()) as any // 定义控制器
  const currentConversationId = useRef(conversationId || generateUUIDv4())
  const [attachmentModalOpen, setAttachmentModalOpen] = useState(false)
  const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({});
  const [supportKnowledge,setSupportKnowledge] = useState(false)


  // 添加状态
  const [knowledgeBases, setKnowledgeBases] = useState([])
  const [selectedKnowledgeIds, setSelectedKnowledgeIds] = useState([])
  const [isModalOpen, setIsModalOpen] = useState(false)

  // 获取知识库列表
  useEffect(() => {
    const fetchKnowledgeBases = async () => {
      try {
        const { data } = await readFileLibDatabase(1, 100)
        setKnowledgeBases(data || [])
      } catch (error) {
        console.error('获取知识库列表失败:', error)
      }
    }
    fetchKnowledgeBases()
  }, [])

  const {
    messages,
    chatId,
    limitInfo,
    updateChatId,
    createSendMsg,
    updateLoadingMessage,
    loadHistoryMsg,
    updateCurrentMessage,
    updateCurrentMessageImage,
    destroyChat,
    setShowGuideQuestion,
    updateCitationsMessage,
    setIsRunning,
    setUpIsLoading
  } = useChatStore()
  const currentChatIdRef = useRef(null)
  const inputRef = useRef(null)

  // ------埋点------
  const { applicationBuriedEvent } = useBuriedEvent()

  /**
   * 记录会话切换状态，等待消息加载完成时，控制表单在新会话自动展开
   */
  const changeChatedRef = useRef(false)

  const [uploadedFiles, setUploadedFiles] = useState([])

  useEffect(() => {
    if (!chatId) return
    setInputLock({ locked: false, reason: '' })
    chattingFun('again')
    setShowWhenLocked(false)
    currentChatIdRef.current = chatId
    changeChatedRef.current = true
    setFormShow(false)
    if (disabled) {
      setInputLock({ locked: true, reason: '' })
      chattingFun('locked')
    }
    setDisable_search(true)
    //setLogoUrl('')
    //setImgName('')
    cleanUploadImageInfo()
    clearUploadedFileInfo()
  }, [chatId])

  useEffect(() => {
    if (changeChatedRef.current) {
      changeChatedRef.current = false
      // 新建的 form 技能,弹出窗口并锁定 input
      if (form && messages.length === 0) {
        setInputLock({ locked: true, reason: '' })
        chattingFun('locked')
        setFormShow(true)
        setShowWhenLocked(true)
      }
    }
  }, [messages])

  useEffect(() => {
    setIsRunning(inputLock.locked)
  }, [inputLock])

  const uniqueInputId = useRef('')

  useEffect(() => {
    messageStoplink()
    /* conversationId 每次切换都为uuid 
    可以判断切换智能体 因为开启新会话的assistantId重复 */
    updateChatId(assistantId)
    uniqueInputId.current = uniqueId('chat_')
    if (conversationId && currentConversationId.current !== conversationId) {
      currentConversationId.current = conversationId
    }
    return () => {
      controller.current.abort()
      controller.current = new AbortController()
      destroyChat()
      uniqueInputId.current = ''
      //setLogoUrl('')
      cleanUploadImageInfo()
      currentConversationId.current = conversationId
    }
  }, [assistantId, conversationId])

  function messageStoplink() {
    // 如果当前控制器已经被中止，则无需再次中止
    if (controller.current.signal.aborted) {
      console.log('信号已经中止，无需再次中止')
      return
    }

    // 中止当前控制器
    controller.current.abort()

    // 重置控制器
    controller.current = new AbortController()
    isPaused.current = false
  }

  // 对话信息更新
  useEffect(() => {
    inputRef.current.value = ''
    const len = messages.length
    if (len > 0 && messages[len - 1].role === 'user') {
      // 触发loading
      updateLoadingMessage()
      // 对话
      handleChat(assistantId, messages, uniqueInputId.current)
    }
  }, [messages])

  const handleRecognizedText = (text: string) => {
    if (inputRef.current) {
      inputRef.current.value = text
    }
  }

  const handleSendClick = async (imageUrl = '', imageName = '', fileUrl = '', fileName = '', files = []) => {
    if (!prompt) {
      showWarning('提示', ROLE_EMPTY_ERROR)
      return
    }
    applicationBuriedEvent({
      page: '智能体配置页面',
      event_name: '【提问发送】按钮',
      data_id: assistantId || null
    })

    // 解除锁定状态下 form 按钮开放的状态
    setShowWhenLocked(false)
    // 关闭引导词
    setShowGuideQuestion(false)
    // 收起表单
    // formShow && setFormShow(false)
    setFormShow(false)

    const value = inputRef.current.value
    // 检查是否所有文件都已完成解析
    const allFilesCompleted = uploadedFiles.every(file => file.status === FileStatus.COMPLETED)
    if (!allFilesCompleted) {
      showMessage({
        content: '请等待所有文件解析完成后再发送',
        type: 'warning'
      })
      return
    }

    if (value.trim() === '' && !uploadImageInfo.fileUrl && !imageUrl && uploadedFiles.length === 0) return
    if (value.length > 2048) {
      showWarning('提示', '问题输入不能大于2048个字符')
      return
    }

    const event = new Event('input', { bubbles: true, cancelable: true })
    inputRef.current.value = ''
    inputRef.current.dispatchEvent(event) // 触发调节input高度

    console.log('currentUploadFileType.current:', currentUploadFileType.current, uploadedFileName, uploadImageInfo.fileUrl)
    if (currentUploadFileType.current === 'image') {
      if (uploadImageInfo.fileUrl || imageUrl) {
        createSendMsg('image_url', '', uploadImageInfo.fileUrl || imageUrl, uploadImageInfo.fileName || imageName)
        //setLogoUrl('')
        //setImgName('')
        cleanUploadImageInfo()
      }
    } else if (currentUploadFileType.current === 'file') {
      if (uploadedFiles.length > 0) {
        // 发送多个文件消息
        uploadedFiles.forEach(file => {
          createSendMsg('file_url', '', '', '', file.fileUrl, file.fileName)
        })
        clearUploadedFileInfo()
      } else if (files.length >0 ){
        // 发送多个文件消息
        files.forEach(file => {
          createSendMsg('file_url', '', '', '', file.url, file.name)
        })
        clearUploadedFileInfo()
      }else if (uploadedFileName || fileUrl) {
        // 兼容单文件发送
        createSendMsg('file_url', '', '', '', uploadedFileUrl || fileUrl, uploadedFileName || fileName)
        clearUploadedFileInfo()
      }
    }

    if (value) {
      createSendMsg('text', value, '')
    }
    // 锁定 input
    setInputLock({ locked: true, reason: '' })
    chattingFun('locked')
    // 滚动聊天到底
    const messageDom = document.getElementById('message-panne')
    if (messageDom) {
      messageDom.scrollTop = messageDom.scrollHeight
    }
  }

  function handleApplicationErrors(jsonData, appId) {
    if (jsonData && jsonData.code && [4001, 4002, 4003].includes(jsonData.code)) {
      switch (jsonData.code) {
        case 4001:
          console.error('4001 : 智能体已下线')
          updateCurrentMessage(appId, `该智能体已下线 ，无法访问，请联系作者${userName}或超级管理员`, -1)
          showMessage({
            content: `该智能体已下线 ，无法访问，请联系作者${userName}或超级管理员`,
            type: 'warning'
          })
          break
        case 4002:
          console.error('4002 : 智能体已删除')
          updateCurrentMessage(appId, `该智能体已删除，无法访问，请联系作者${userName}或超级管理员`, -1)
          showMessage({
            content: `该智能体已删除，无法访问，请联系作者${userName}或超级管理员`,
            type: 'warning'
          })
          break
        case 4003:
          console.error('4003 : 智能体已私密')
          updateCurrentMessage(appId, `该智能体已私密，无法访问，请联系作者${userName}或超级管理员`, -1)
          showMessage({
            content: `该智能体已私密，无法访问，请联系作者${userName}或超级管理员`,
            type: 'warning'
          })
          break
      }
      return true // 表示已经处理了特定错误代码，不再继续执行后续代码
    }
    return false
  }
  let noText = true // 当没有文本时，提示：发生了助理解决不了的问题，工程师正在努力恢复，请稍等。
  let noImage = true // 当没有图片时，提示：发生了助理解决不了的问题，工程师正在努力恢复，请稍等。
  const handleChat = async (appId: string, msg: ChatMessageType[], uid) => {
    chattingFun('')
    const chatMsg = getValidChatMsg(msg, prompt, limitInfo)

    const signal = controller.current.signal

    let currentFileId
    if (chatMsg && chatMsg.length > 0 && chatMsg[chatMsg.length - 1]?.content[0]?.file_url?.name) {
      currentFileId = uploadedFileId
    }

    try {

      const response = await fetch(chatUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'app-id': appId,
          Accept: 'text/event-stream'
        },
        body: JSON.stringify({
          app_id: appId,
          is_preview: 1,
          messages: chatMsg,
          sso_key: 'test',
          conversation_id: conversationId,
          disable_search: !disable_search,
          is_regenerate,
          conversation_file_id: currentFileId,
          'chat_alias_id': currentConversationId.current,
          extension_knowledge_ids : selectedKnowledgeIds
        }),
        signal
      })

      // 检查HTTP状态码
      if (!response.ok) {
        throw new Error(`请求失败，状态码: ${response.status}`)
      }

      const contentType = response.headers.get('Content-Type')
      if (contentType?.includes('application/json')) {
        try {
          // 使用克隆的响应对象来读取一次性的文本内容
          const clonedResponse = response.clone()
          const text = await clonedResponse.text()
          if (text) {
            const jsonData = JSON5.parse(text)
            if (handleApplicationErrors(jsonData, appId)) return // 如果有特定错误代码，直接返回
          }
        } catch (parseError) {
          console.log(parseError)
          // throw new Error('解析响应体失败')
        }
      }
      const reader = response.body.getReader()
      const decoder = new TextDecoder('utf-8')

      const allCitations = []

      let startThinkTime: number = 0
      let endThinkTime: number = 0
      let thinkTimeFull: boolean = false

      /**
       * 在对话过程中判断应该用哪个方法来更新
       * @param content
       * @param updateParams
       */
      const updateCore = (
        { updateType, content },
        ..._updateParams: [string, string, number?, any?, boolean?, string?, number?]
      ) => {
        const updateParams = _updateParams
        switch (updateType) {
          case 'text':
            updateCurrentMessage(...updateParams)
            break
          case 'viaual':
            updateCurrentMessageImage(content?.detail?.imgUrls?.[0], ...updateParams)
            break
          default:
            break
        }
      }
      const processLine = (line: string) => {
        if (line.startsWith('data: {')) {
          // const mockData = {
          //   choices: [
          //     {
          //       index: 0,
          //       delta: {
          //         content:
          //           '{"msgType": "viaual", "detail": {"type": "viaual", "content": "", "aspectRatio": "1:1", "imgUrls": [{"type": "image", "fileContextId": "2143471846", "filename": "1681751556096_1(3)", "url": "https://baiying-agent-test.oss-cn-beijing.aliyuncs.com/png/2025-04-21/cae823c1-8ddb-4ab6-bf8e-2e9759bf7cd2.png?Expires=1745314845&OSSAccessKeyId=LTAI5t8Ck1wsDJiiB5NbiyGx&Signature=Vds8JqAwR0wTQVJPonqOTmEsktA%3D"}, {"type": "image", "filename": "", "url": ""}, {"type": "image", "filename": "", "url": ""}, {"type": "image", "filename": "", "url": ""}], "imgZipUrl": {"type": "zip", "filename": "zip_1914251681751556096", "url": "https://baiying-agent-test.oss-cn-beijing.aliyuncs.com/zip/2025-04-21/47eff2b2-16a7-4cb2-bd6d-eb06b260739f.zip?Expires=1745314845&OSSAccessKeyId=LTAI5t8Ck1wsDJiiB5NbiyGx&Signature=8BMKSmBtR5C1zVTFZqIwX5e63HQ%3D"}}, "content": "文字生图", "hitPlugin": {"id": "197", "name": "视觉场景-文生图"}, "referenceChatRecordId": "1914251681751556096", "referenceChatRecordMsg": "北京人口", "selectedStatus": 0}',
          //         reasoning_content: '',
          //         polish_content: ''
          //       }
          //     }
          //   ],
          //   citations: [
          //     { type: 'plugin', title: '视觉场景-文生图', url: '', detail: [], file_id: '', knowledge_name: '' }
          //   ],
          //   finish_reason: null,
          //   status: 10,
          //   usage: null,
          //   created: 1745228445,
          //   check_status: 'stop'
          // }
          try {
            const jsonData: ChatResponseType = JSON5.parse(line.slice(6))
            // jsonData.choices = mockData?.choices

            const choice = jsonData?.choices?.[0]
            let content = choice?.delta?.content
            let updateType = 'text'
            try {
              content = JSON.parse(choice?.delta?.content)
              updateType = (content as any)?.msgType || 'text'
            } catch (err) {
              // console.log('err', err)
            }

            let internetCitations
            /**
             * 溯源信息处理
             */
            if (jsonData.citations && jsonData.citations.length > 0) {
              jsonData.citations.forEach(citation => {
                if (citation.type === CITATION_TYPE.knowledge || citation.type === CITATION_TYPE.plugin)
                  // updateCitationsMessage(appId, citation)
                  allCitations.push({ appId, citation })
              })
            }
            if (ASSISTANT_STATUS.includes(jsonData.status)) {
              /**
               * 这里临时由前端增加解决方案
               * 同时存在两条溯源信息时，只显示工具的溯源信息，后期需要后端修改返回，未使用的溯源不返回
               * allCitations判断在后端修改后移除
               */
              if (allCitations.length > 0) {
                let validCitations = [...allCitations]
                allCitations.length = 0

                const citationTypes = Array.from(new Set(validCitations.map(item => item.citation.type)))
                if (citationTypes.length > 1) {
                  validCitations = validCitations.filter(item => item.citation.type === CITATION_TYPE.plugin)
                }

                validCitations.forEach(item => {
                  updateCitationsMessage(item.appId, item.citation)
                })
              }
              // 思考过程处理
              const think = jsonData.choices?.reduce((acc, choice) => acc + (choice.delta?.reasoning_content || ''), '')
              /** 会话消息处理 */
              const text = jsonData.choices?.reduce((acc, choice) => {
                if (updateType === 'viaual') {
                  const content = JSON.parse(choice.delta?.content)
                  return acc + content?.detail?.content || ''
                }
                return acc + (choice.delta?.content || '')
              }, '')
              /**
               * 图片消息处理
               */
              const img = jsonData.choices?.reduce((acc, choice) => {
                if (updateType === 'viaual') {
                  const content = JSON.parse(choice.delta?.content)
                  const imgs = content?.detail?.imgUrls
                  if (imgs?.length > 0) {
                    noImage = false
                  }
                  return acc.concat(imgs)
                }
                return acc
              }, [])
              /* 联网搜索 */
              const hasInternetCitation = jsonData.citations.some(citation => citation.type === 'internet')
              if (think && !startThinkTime) {
                startThinkTime = jsonData.created
              }
              if ((text || img.length) && !endThinkTime) {
                endThinkTime = jsonData.created
              }
              if (think || text || img.length) {
                noText = false
                /* citations =  type = 'internet' 联网搜索 */
                if (hasInternetCitation) {
                  internetCitations = jsonData.citations
                }
                // 判断生成停止
                const chatStopTag: any = isPaused.current ? 'stop' : ''
                if (jsonData.status === AgentStatus.content_illegal) {
                  updateCore(
                    {
                      updateType,
                      content
                    },
                    appId,
                    text,
                    jsonData.status,
                    internetCitations,
                    true,
                    chatStopTag
                  )
                  return true
                } else {
                  // 临时填充思考时间
                  if (endThinkTime && startThinkTime && !thinkTimeFull) {
                    thinkTimeFull = true

                    updateCore(
                      {
                        updateType,
                        content
                      },
                      appId,
                      '',
                      jsonData.status,
                      internetCitations,
                      false,
                      '',
                      endThinkTime - startThinkTime
                    )
                  }
                  updateCore(
                    {
                      updateType,
                      content
                    },
                    appId,
                    text,
                    jsonData.status,
                    internetCitations,
                    false,
                    think,
                    chatStopTag
                  )
                }
              }
            }
          } catch (e) {
            console.error('解析 JSON 失败:', e)
            chattingFun('')
          }
        } else if (line === 'data: [DONE]') {
          if (noText && noImage) {
            updateCurrentMessage(appId, '发生了助理解决不了的问题，工程师正在努力恢复，请稍等。', -1)
            chattingFun('')
          }
          return true
        } else if (line.startsWith('data: Error')) {
          // 将异常处理文本内容直接输出到对话列表
          updateCurrentMessage(appId, line.substring(6), -1)
        }
      }
      chattingFun('stop')

      let buffer = ''
      while (true) {
        if (isPaused.current) {
          break
        }
        const { done, value } = await reader.read()
        if (done) break
        if (uid !== uniqueInputId.current) {
          break
        }
        const chunk = decoder.decode(value, { stream: true })
        buffer += chunk
        const lines = buffer.split('\r\n')
        buffer = lines.pop() || ''
        for (const line of lines) {
          if (processLine(line)) {
            break
          }
        }
        // 暂停会话参数判断
        if (isPaused.current) {
          controller.abort() // 取消fetch请求
          isPaused.current = false
          break
        }
      }
      console.log('数据处理结束')
    } catch (error) {
      console.error('请求过程中出现问题:', error)
      if (isPaused.current) {
        if (noText && noImage) {
          updateCitationsMessage(appId, {}, 'clear')
          updateCurrentMessage(appId, '回答已暂停', -1)
        }
        return
      }
      updateCurrentMessage(appId, '发生了助理解决不了的问题，工程师正在努力恢复，请稍等。', -1)
    } finally {
      controller.current = new AbortController()
      isPaused.current = false
      setInputLock({ locked: false, reason: '' })
      chattingFun('again')
      setIs_regenerate(false)
    }
  }

  // 监听重发消息事件
  useEffect(() => {
    const handleCustomEvent = e => {
      // 中断会话 detail.send = 'stop'
      if (e.detail.send && e.detail.send === 'stop') {
        isPaused.current = true
        controller.current.abort() // 中断请求
        return
      }
      if (!showWhenLocked && inputLock.locked) {
        console.error('弹窗已锁定，消息无法发送')
        return
      }
      const { send, message, imageUrl, imageName, files } = e.detail
      inputRef.current.value = message
      if (send) {
        // const len = messages.length
        // if (len > 0 && messages[len - 1].role === 'assistant') {
        //   let messagesNew = messages.slice(0, len - 1)
        //   /* 如果上条是溯源 插件等信息 一并删除 */
        //   if (messages[len - 2].role === 'citations') {
        //     messagesNew = messagesNew.slice(0, messagesNew.length - 1)
        //   }
        //   const history = { messages: messagesNew }
        //   loadHistoryMsg(history, '')
        // }
        // setIs_regenerate(true)
        handleSendClick(imageUrl, imageName, '' , '' , files)
      } else if (imageUrl){
        //setLogoUrl(imageUrl)
        //setImgName(imageName)
        setUploadImageInfo({
          fileId: imageName,
          fileName: imageName,
          fileUrl: imageUrl,  
          status: FileStatus.COMPLETED,
          progress: 100,
          type: 'image'
        })
      }else if(files && files.length > 0){
        setUploadedFiles(files.map(item => ({
          fileId:item.url,
          fileName:item.name,
          fileUrl:item.url,
          status: FileStatus.COMPLETED,
          progress: 100,
          type: 'file'
        })))
      }
    }
    document.addEventListener('userResendMsgEvent', handleCustomEvent)
    return () => {
      document.removeEventListener('userResendMsgEvent', handleCustomEvent)
    }
  }, [inputLock.locked, showWhenLocked])

  // message
  const noLimitsMessage = () => {
    showMessage({
      content: tips,
      type: 'warning'
    })
  }
  // 点击引导词
  const handleClickGuideWord = message => {
    if (!showWhenLocked && inputLock.locked) {
      console.error('弹窗已锁定，消息无法发送')
      return
    }
    inputRef.current.value = message
    regenerate()
    handleSendClick()
  }

  // auto input height
  const handleTextAreaHeight = e => {
    const textarea = e.target
    textarea.style.height = 'auto'
    textarea.style.height = textarea.scrollHeight + 'px'
  }

  const handleSelectChat = e => {
    console.log(e, 'e')
  }
  // 推荐问题list
  const recomConversation = async e => {
    inputRef.current.value = e.flow_description
    handleSendClick()
  }
  /* 鼠标滑动显示隐藏icon */
  const [mouseHid, setMouseHid] = useState(true)
  const recohandleMouseEnter = () => {
    setMouseHid(true)
  }
  const recohandelMouseLeave = () => {
    setMouseHid(true)
  }
  /* 重发字段 */
  const [is_regenerate, setIs_regenerate] = useState(false)
  /* switch 联网搜索 */
  const [disable_search, setDisable_search] = useState(false)
  const handleChange = checked => {
    // if (modelName === 'deepseek-r1') {
    //   showMessage({
    //     content: '智能体所选模型，当前暂不支持联网搜索',
    //     type: 'warning'
    //   })
    //   return
    // }
    setDisable_search(checked)
  }
 
  // 添加文件状态类型
  const FileStatus = {
    UPLOADING: 'uploading',
    PARSING: 'parsing',
    COMPLETED: 'completed',
    ERROR: 'error'
  } as const

  //const [logoUrl, setLogoUrl] = useState('')
  //const [imgName, setImgName] = useState('')
  const [uploadImageInfo, setUploadImageInfo] = useState({
    fileId: '',
    fileName: '',
    fileUrl: '',  
    status: '',
    progress: 0,
    type: ''
  })

  const cleanUploadImageInfo = () => {
    setUploadImageInfo({
      fileId: '',
      fileName: '',
      fileUrl: '',
      status: '',
      progress: 0,
      type: ''
    }) 
  }

  useEffect(()=>{
    setUploading(uploadImageInfo.fileUrl.length > 0 || uploadedFiles.length > 0)
  },[uploadImageInfo, uploadedFiles])  

  const handleImgUpload = async file => {
    try {
      setUpIsLoading(true)
      setUploadedFiles([])
      
      // 先添加文件到列表，状态为上传中
      const newFile = {
        fileId: '',
        fileName: file.name,
        fileUrl: '',
        status: FileStatus.UPLOADING,
        progress: 0,
        type: 'image'
      }
  
      setUploadImageInfo(newFile)
      const formData = new FormData()
      formData.append('file', file)
      
      const response: any = await axios.post('/api/v1/common/upload/icon', formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        },
        // onUploadProgress: (progressEvent) => {
        //   const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
        //   setUploadImageInfo(prev => ({
        //     ...prev,
        //     progress: percentCompleted,
        //     status: percentCompleted === 100 ? FileStatus.PARSING : FileStatus.UPLOADING
        //   }))
        // }
      })
  
      currentUploadFileType.current = 'image'
      
      // 直接更新当前上传信息的状态和URL，而不是创建新的对象
      setUploadImageInfo(prev => ({
        ...prev,
        fileId: response.file_id,
        fileName: file.name, 
        fileUrl: response.file_path.split("?")[0],
        status: FileStatus.COMPLETED,
        progress: 100
      }))
  
      clearUploadedFileInfo()
      return response
    } catch (err) {
      setUploadImageInfo(prev => ({
        ...prev,
        status: FileStatus.ERROR
      }))
      console.error('Error uploading file:', err)
      throw err
    } finally {
      setUpIsLoading(false)
    }
  }

  const uploadImage = async options => {
    const { onSuccess, onError, file, onProgress } = options
    try {
      const response: any = await handleImgUpload(file)
      onSuccess({ file, preview_url: response?.file_path })
    } catch (err) {
      console.error('Error uploading file:', err)
      onError({ err })
    }
  }

  const UploadProps: UploadProps = {
    name: 'file',
    multiple: false,
    maxCount: 1,
    // defaultFileList,
    showUploadList: false,
    accept: '.png, .jpg, .jpeg',
    customRequest: uploadImage,
    beforeUpload: file => {
      // 文件上传前校验
      if (file.size > 5120000) {
        showMessage({
          content: '文件过大，请重新选择5M以内的文件',
          type: 'error'
        })
        return Upload.LIST_IGNORE
      }
      const fileType = file.name.split('.').pop()?.toLowerCase()
      if (!['png', 'jpg', 'jpeg'].includes(fileType)) {
        showMessage({
          content: `不支持的文件类型${fileType},已移除`,
          type: 'warning'
        })
        return false
      }
      return true
    },
    onChange(info) {
      const { status } = info.file
      if (status !== 'uploading') {
        // console.log(info.file, info.fileList)
      }
      if (status === 'done') {
        // onSelect(info.file.response.data.file_path)
        // message.success(`${info.file.name} file uploaded successfully.`)
      } else if (status === 'error') {
        // message.error(`${info.file.name} file upload failed.`)
      }
    },
    onDrop(e) {
      console.log('Dropped files', e.dataTransfer.files)
    },
    onRemove: file => {
      //setLogoUrl('')
      //setImgName('')
      cleanUploadImageInfo()
    }
  }

  const baseStyles = {
    // backgroundColor: conversation ? 'rgba(245,245,245)' : 'white'
    backgroundColor: 'rgba(245,245,245)'
  }

  const currentUploadFileType = useRef('')
  const [uploadedFileId, setUploadedFileId] = useState()
  const [uploadedFileName, setUploadedFileName] = useState('')
  const [uploadedFileUrl, setUploadedFileUrl] = useState('')

  const clearUploadedFileInfo = () => {
    // setUploadedFileId(undefined)
    setUploadedFileName('')
    setUploadedFileUrl('')
    setUploadedFiles([])
  }

  const handleUpload = async file => {
    try {
      setUpIsLoading(true)
      //setImgName('')
      //setLogoUrl('')
      cleanUploadImageInfo()

      // 先添加文件到列表，状态为上传中
      const newFile = {
        fileId: '',
        fileName: file.name,
        fileUrl: '',
        status: FileStatus.UPLOADING,
        progress: 0
      }
      setUploadedFiles(prev => [...prev, newFile])
      
      const formData = new FormData()
      formData.append('file', file)
      
      const response: any = await axios.post('/api/v1/knowledge/upload_and_parse', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
          'conversation-id': currentConversationId.current
        },
        onUploadProgress: (progressEvent) => {
          const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          // 更新上传进度和状态
          setUploadedFiles(prev => prev.map(item => 
            item.fileName === file.name 
              ? {
                  ...item,
                  progress: percentCompleted,
                  status: percentCompleted === 100 ? FileStatus.PARSING : FileStatus.UPLOADING
                }
              : item
          ))
        }
      })
    
      currentUploadFileType.current = 'file'
      
      // 上传完成后更新文件信息和状态
      setUploadedFiles(prev => prev.map(item => 
        item.fileName === file.name 
          ? {
              fileId: response.file_id,
              fileName: response.file_name,
              fileUrl: response.file_url.split("?")[0],
              status: FileStatus.COMPLETED,
              progress: 100
            }
          : item
      ))
      
      setUploadedFileId(response.file_id)
      setUploadedFileName(response.file_name)
      setUploadedFileUrl(response.file_url)
      
      return response
    } catch (err) {
      // 发生错误时更新状态
      setUploadedFiles(prev => prev.map(item => 
        item.fileName === file.name 
          ? {
              ...item,
              status: FileStatus.ERROR
            }
          : item
      ))
      console.error('Error uploading file:', err)
      throw err
    }
  }

  const customUploadFile = async options => {
    const { onSuccess, onError, file, onProgress } = options
    try {
      await handleUpload(file)
      onSuccess({ file })
    } catch (err) {
      console.error('Error uploading file:', err)
      onError({ err })
    } finally {
      setUpIsLoading(false)
    }
  }

  const upFileProps: UploadProps = {
    name: 'upFile',
    multiple: true,
    maxCount: 5,
    showUploadList: false,
    accept: '.doc, .docx, .pdf, .ppt, .pptx',
    customRequest: customUploadFile,
    onChange(info) {
      console.log('fileList Change======》', info.fileList, info.file)
      if (info.file.status === 'done') {
        // message.success(`${info.file.name} 上传成功`);
        setUpIsLoading(false)
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上传失败`)
        setUpIsLoading(false)
      }
    },
    beforeUpload: file => {
      const sizeOk = file.size / 1024 / 1024 < 10
      if (!sizeOk) {
        showMessage({
          content: `${file.name} 超过${10}M,已移除`,
          type: 'warning'
        })
        return false
      }

      const fileType = file.name.split('.').pop()?.toLowerCase()
      if (!ACCEPT_FILES.includes(fileType)) {
        showMessage({
          content: `不支持的文件类型${fileType},已移除`,
          type: 'warning'
        })
        return false
      }
      return true
    },
    onDrop(e) {
      console.log('Dropped files', e.dataTransfer.files)
    },
    onRemove: file => {
      console.log('onRemove ', file)
      clearUploadedFileInfo()
    }
  }

  const [dragOver, setDragOver] = useState(false)
  // 拖拽事件处理
  const onDragOver = useCallback(e => {
    console.log('onDragOver', e)
    e.preventDefault()
    setDragOver(true)
  }, [])

  const onDragLeave = useCallback(e => {
    console.log('onDragLeave', e)
    e.preventDefault()
    setDragOver(false)
  }, [])

  const onDrop = useCallback(e => {
    e.preventDefault()
    setDragOver(false)
    const files = e.dataTransfer.files
    if (files.length === 0) return
    if (files.length > 1) {
      message.warning(`仅支持单个文件上传`)
      return
    }
    const file = files[0]
    const sizeLimit = file.size / 1024 / 1024 < 10
    const fileType = file.name.split('.').pop()?.toLowerCase()
    if (!ACCEPT_FILES.includes(fileType)) {
      showMessage({
        content: `不支持的文件类型${fileType},已移除`,
        type: 'warning'
      })
      return
    }
    // file详情页判断是否为图片格式
    // const isImage = ['jpg', 'jpeg', 'png'].includes(fileType)
    // if (isImage) {
    //   sizeLimit = file.size / 1024 / 1024 < 5
    // }
    if (!sizeLimit) {
      showMessage({
        content: `${file.name} 超过${sizeLimit}M,已移除`,
        type: 'warning'
      })
    }
    // if (isImage) {
    //   handleImgUpload(file)
    // } else {
    //   handleUpload(file)
    // }
    handleUpload(file)
  }, [])

  const [overlayVisible, setOverlayVisible] = useState(false)
  const showOverlay = () => {
    setOverlayVisible(true)
  }

  const hideOverlay = () => {
    setOverlayVisible(false)
  }

  return (
    <div className="absolute bottom-[16px] w-full pt-1 dark:bg-[#1B1B1B]" style={{ ...baseStyles }}>
      {/* 推荐问题 */}
      <RecommendedCont
        mouseHid={mouseHid}
        conversation={conversation}
        regenerate={() => {
          regenerate()
          setTimeout(() => {
            // 滚动聊天对话
            const messageDom = document.getElementById('message-panne')
            if (messageDom) {
              messageDom.scrollTop = messageDom.scrollHeight
            }
          }, 500)
        }}
        recomConversation={recomConversation}
        recommendedHid={recommendedHid}
        list={questions}
        chatId={chatId}
        locked={inputLock.locked}
        chatsRef={'RecommendedCont'}
        handleSelectChat={handleSelectChat}
        onClick={handleClickGuideWord}
        recohandleMouseEnter={recohandleMouseEnter}
        recohandelMouseLeave={recohandelMouseLeave}
      ></RecommendedCont>
      {/* <div className={`relative ${clear && 'pl-9'}`}> */}
      <div
        className={'relative'}
        style={{ bottom: '0' }}
        onDragOver={onDragOver}
        onDragLeave={onDragLeave}
        onDrop={onDrop}
      >
        {dragOver && (
          <div className="chat-file-upload-container flex flex-col items-center justify-center">
            <div className="flex flex-col items-center justify-center">
              <div className="common-upload-main-text">文件拖拽到此处可上传</div>
              {/* <div className="common-upload-sub-text mx-[32px] text-start">
                上传图片(大小不超过5MB，支持.jpg/.jpeg/.png)
              </div> */}
              <div className="common-upload-sub-text mx-[32px] text-start">
                支持上传的文件(大小不能超过10MB),接受.pdf,.docx,.doc,.ppt,pptx，wav, pcm, ogg-opus, speex, silk, mp3,
                m4a, aac, amr格式语音文件
              </div>
            </div>
          </div>
        )}
        {/* form */}
        {formShow && (
          <div className="relative">
            <div className="absolute bottom-2 left-0 w-[50%] min-w-80 rounded-md border bg-[#fff] px-4 py-2">
              {inputForm}
            </div>
          </div>
        )}
        {/* send */}
        <div
          className={
            // conversation ? 'chatInput_case_absIcon absolute z-10 flex gap-2' : 'absolute right-3 top-4 z-10 flex gap-2'
            'chatInput_case_absIcon absolute z-10 flex gap-2'
          }
        >
          {/* <img src={MicrophoneIcon} alt="" className="cursor-pointer" onClick={showOverlay} /> */}
          <div
            id="bs-send-btn"
            className="flex cursor-pointer items-center justify-center rounded-sm"
            onClick={() => {
              if (disabled) {
                noLimitsMessage()
                return
              }
              !inputLock.locked && handleSendClick()
            }}
          >
            <svg width="46" height="30" viewBox="0 0 46 30" fill="none" xmlns="http://www.w3.org/2000/svg">
              <rect width="46" height="30" rx="15" fill="url(#paint0_linear_4810_8446)" />
              <g clipPath="url(#clip0_4810_8446)">
                <path
                  d="M27.5282 8.17621L15.6132 12.8386C14.7876 13.1617 14.7595 14.3197 15.5685 14.6824L19.8811 16.6156C20.105 16.7159 20.2841 16.8951 20.3845 17.119L22.3177 21.4315C22.6804 22.2405 23.8384 22.2125 24.1615 21.3869L28.8239 9.47186C29.1416 8.65979 28.3403 7.85845 27.5282 8.17621Z"
                  fill="white"
                />
              </g>
              <defs>
                <linearGradient
                  id="paint0_linear_4810_8446"
                  x1="0"
                  y1="15"
                  x2="46"
                  y2="15"
                  gradientUnits="userSpaceOnUse"
                >
                  <stop stopColor="#3B74FB" />
                  <stop offset="0.505" stopColor="#6468F7" />
                  <stop offset="1" stopColor="#9659F2" />
                </linearGradient>
                <clipPath id="clip0_4810_8446">
                  <rect width="20" height="20" fill="white" transform="translate(13 5)" />
                </clipPath>
              </defs>
            </svg>
          </div>
        </div>
        {/* question */}
        <div className="chatInput_case flexCol pb-1.5">
          <div className="flexRowStart flexRowJustBet pb-2">
            <div className="flexRowStart">
              {supportSearch && (
                <div className="flexRowStart">
                  <span>联网搜索</span>
                  <div className="applicationEdit_switchCase">
                    <SwitchComponent
                      style={{ marginLeft: '4px' }}
                      checked={disable_search}
                      onChange={handleChange}
                      size="small"
                      disabled={disabled}
                    />
                  </div>
                  <Divider type="vertical" />
                </div>
              )}
  
              <div className='mr-2'>
                <Dropdown placement="topLeft"
                  menu={{ 
                    items: [
                      {
                        key: 'image',
                        label: (
                          <Tooltip title="支持单个 jpg、jpeg、png 格式文件，文件不超过 5MB" placement="right" overlayStyle={{ fontSize: '12px' }}>
                            <div className="text-[13px]">图片上传</div>
                          </Tooltip>
                        ),
                        onClick: () => {
                          const input = document.createElement('input')
                          input.type = 'file'
                          input.accept = '.png, .jpg, .jpeg'
                          input.multiple = false
                          input.onchange = (e) => {
                            const file = (e.target as HTMLInputElement).files?.[0]
                            if (file) {
                              handleImgUpload(file)
                            }
                          }
                          input.click()
                        }
                      },
                      {
                        key: 'file',
                        label: (
                          <Tooltip title="支持 pdf/doc/txt/md/ppt等，每个最多20MB，最多10个" placement="right" overlayStyle={{ fontSize: '12px' }}>
                            <div className="text-[13px]">文件上传</div>
                          </Tooltip>
                        ),
                        onClick: () => {
                          const input = document.createElement('input')
                          input.type = 'file'
                          input.accept = '.pdf,.docx,.doc,.ppt,.pptx,.txt,.md'
                          input.multiple = true
                          input.onchange = (e) => {
                            const files = (e.target as HTMLInputElement).files
                            if (files.length + uploadedFiles.length > 10) {
                              showMessage({
                                content: '最多只能上传10个文件',
                                type: 'warning'
                              })
                              return
                            }
                            if (files) {
                              Array.from(files).forEach(file => {
                                handleUpload(file)
                              })
                            }
                          }
                          input.click()
                        }
                      }
                    ]
                  }}
                >
                  <div 
                    className="bg-slate-50 inline-flex cursor-pointer items-center rounded-md border border-gray-200 px-2 py-1 hover:bg-gray-50"
                  >
                    <Paperclip className="mr-1 h-4 w-4" />
                    <span className="text-[13px]">添加附件</span>
                    <svg className="ml-1 h-4 w-4" viewBox="0 0 16 16" fill="currentColor">
                      <path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z" />
                    </svg>
                  </div>
                </Dropdown>
              </div>

              {supportKnowledge && <div className='bg-slate-50 rounded-md'>
                <Tooltip placement="top">
                  <div 
                    className="inline-flex cursor-pointer items-center rounded-md border px-3 py-1 hover:bg-gray-50"
                    onClick={() => !disabled && setIsModalOpen(true)}
                  >
                    <BookOpen className="mr-1 h-4 w-4" />
                    <span className="text-[13px]">{selectedKnowledgeIds.length ? `已选${selectedKnowledgeIds.length}个` : '知识库'}</span>
                    <svg className="ml-1 h-4 w-4" viewBox="0 0 16 16" fill="currentColor">
                      <path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z" />
                    </svg>
                  </div>
                </Tooltip>
                    
                <Modal
                  title="选择知识库"
                  open={isModalOpen}
                  onOk={() => setIsModalOpen(false)}
                  onCancel={() => setIsModalOpen(false)}
                  width={600}
                  style={{ 
                    left: '0',
                    marginBottom: '8px',
                    marginTop: '200px',
                    transform: 'none',
                    top: 'auto',
                  }}
                  getContainer={false}
                  className="knowledge-base-modal"
                >
                  <div className="max-h-[400px] overflow-y-auto">
                    <Checkbox.Group 
                      value={selectedKnowledgeIds}
                      onChange={(values) => setSelectedKnowledgeIds(values)}
                    >
                      <div className="grid grid-cols-3 gap-2">
                        {knowledgeBases.map(kb => (
                          <Checkbox key={kb.id} value={kb.id} className="p-2">
                            {kb.name}
                          </Checkbox>
                        ))}
                      </div>
                    </Checkbox.Group>
                  </div>
                </Modal>
              </div>}
            </div>
            
            <span className="chatInput_case_title pr-1.5">
              {modelName === 'deepseek-r1' && supportSearch && (
                <span className="mr-[8px]">当前联网搜索服务为百应自研联网搜索服务</span>
              )}
              模型：{modelName || '--'}
            </span>
          </div>
          
          <div className='border-[1px] rounded-lg'>
            {(uploadImageInfo.fileUrl || uploadImageInfo.status === FileStatus.UPLOADING) && (
              <div className="flexRowStart chatInput_case_uploadCase pl-1">
              <div className="chatInput_case_uploadposCase relative">
                <div className="w-[60px] h-[60px] rounded relative">
                  {uploadImageInfo.status === FileStatus.UPLOADING ? (
                    <div className="w-full h-full flex items-center justify-center bg-gray-50 rounded">
                      <Spin size="small" />
                    </div>
                  ) : (
                    <img 
                      src={uploadImageInfo.fileUrl} 
                      className="w-full h-full object-cover rounded" 
                      alt="上传图片"
                    />
                  )}
                  <div 
                    className="absolute -top-2 -right-2 cursor-pointer bg-white rounded-full shadow-md p-0.5"
                    onClick={() => { cleanUploadImageInfo() }}
                  >
                    <svg
                      width="14"
                      height="14"
                      viewBox="0 0 14 14"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                    >
                      <circle cx="7" cy="7" r="7" fill="#C8C8C9" />
                      <path d="M5 5L9 9" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                      <path d="M5 9L9 5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                    </svg>
                  </div>
                </div>
              </div>
            </div>
            )}
          
            <div className="flex w-full overflow-x-auto px-1" style={{ scrollbarWidth: 'thin' }}>
              <div className="flex gap-2 whitespace-nowrap">
                {uploadedFiles.map((file, index) => (
                  <div key={file.file_name} className="inline-flex chat-input-file-upload-case">
                    <div className="chatInput_case_uploadposCase relative" style={{ width: '200px', flex: '0 0 auto' }}>
                      <img src={getFileIconByFileName(file.fileName)} alt="" className="h-[32px] w-[32px] flex-shrink-0" />
                      <div className="relative flex-1 min-w-0 ml-2">
                        <Tooltip title={file.fileName}>
                          <span className="block truncate pr-6 mb-1 text-[13px]">{file.fileName}</span>
                        </Tooltip>
                        <div className="text-xs text-gray-500 mb-1">
                          {file.status === FileStatus.UPLOADING && `上传中 ${file.progress}%`}
                          {file.status === FileStatus.PARSING && '解析中...'}
                          {file.status === FileStatus.COMPLETED && '解析完成'}
                          {file.status === FileStatus.ERROR && '上传失败'}
                        </div>
                        {file.status === FileStatus.UPLOADING && (
                          <div className="absolute bottom-[-4px] left-0 w-full h-1 bg-gray-200 rounded">
                            <div 
                              className="h-full bg-blue-500 rounded transition-all duration-300" 
                              style={{ width: `${file.progress}%` }}
                            />
                          </div>
                        )}
                        <svg
                          className="chat-file-remove-icon cursonCase absolute right-0 top-2"
                          onClick={() => {
                            setUploadedFiles(prev => prev.filter((_, i) => i !== index))
                          }}
                          width="14"
                          height="14"
                          viewBox="0 0 14 14"
                          fill="none"
                          xmlns="http://www.w3.org/2000/svg"
                        >
                          <circle cx="7" cy="7" r="7" fill="#C8C8C9" />
                          <path d="M5 5L9 9" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                          <path d="M5 9L9 5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                        </svg>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
            <div className="textarea-container">
              <Textarea
                id="bs-send-input"
                ref={inputRef}
                rows={1}
                disabled={inputLock.locked}
                onInput={handleTextAreaHeight}
                placeholder={
                  inputLock.locked
                    ? inputLock.reason
                    : '请输入问题至对话框内，Enter发送，Shift+Enter换行'
                }
                className={
                  'border-none text-md h-[56px] min-h-6 resize-none py-4 scrollbar-hide dark:bg-[#2A2B2E]' + (form && ' pl-10')
                }
                style={{
                  fontSize: '14px',
                  height: '56px',
                  marginTop: '0px',
                }}
                onKeyDown={event => {
                  if (event.key === 'Enter' && !event.shiftKey) {
                    event.preventDefault()
                    !inputLock.locked && handleSendClick()
                  }
                }}
              ></Textarea>
              {/* <SpeechRecognizer
                visible={overlayVisible}
                onClose={hideOverlay}
                onRecognizedText={handleRecognizedText}
              ></SpeechRecognizer> */}
            </div>
          </div>
          <div className="chatInput_footer_tips">内容由AI生成，请仔细甄别，无法确保真实准确。</div>
        </div>
      </div>
    </div>
  )
}
